//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.3
#include "uart_bsp.h"
#include <stdio.h>
#include <string.h>

/*串口总管理结构体*/
typedef struct
{
    WHT_UART_enum Name;     //串口号
    WHT_UART_Info_t Info;   //提供给外部
    WHT_UART_Cache_t* Cache;//外设缓存,由外部提供

    FunctionalState Dma_Receive;        //串口DMA功能
    WHT_DMA_Config_t DMA_Send_Config;   //DMA配置
    WHT_DMA_Config_t DMA_Receive_Config;//DMA配置
}WHT_Data_t;


static WHT_Data_t WHT_UART1;
static WHT_Data_t WHT_UART2;
static WHT_Data_t WHT_UART3;
static WHT_Data_t WHT_UART4;
static WHT_Data_t WHT_UART5;

#define WHT_UART     ((WHT_Data_t*)cache->Private_Data)//简化操作


/*串口GPIO初始化*/
static void WHT_UART_BSP_GPIO_Init(const WHT_UART_Config_t *config)
{
    switch (config->Name)
    {
    case UART_1:
        #if 1
        WHT_GPIO_BSP.WHT_Set_Clock(PortA, ENABLE);
        WHT_GPIO_BSP.WHT_Set_State(PortA, Pin9 | Pin10, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortA, Pin9, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortA, Pin10, Mode_IPU);
        #else
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
        GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, DISABLE);
        WHT_GPIO_BSP.WHT_Set_Clock(PortB, ENABLE);
        WHT_GPIO_BSP.WHT_Set_State(PortB, Pin6 | Pin7, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin6, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin7, Mode_IPU);
        #endif
        break;
    case UART_2:
        WHT_GPIO_BSP.WHT_Set_Clock(PortA, ENABLE);
        WHT_GPIO_BSP.WHT_Set_State(PortA, Pin2 | Pin3, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortA, Pin2, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortA, Pin3, Mode_IPU);
        break;
    case UART_3:
        WHT_GPIO_BSP.WHT_Set_Clock(PortB, ENABLE);
        WHT_GPIO_BSP.WHT_Set_State(PortB, Pin10 | Pin11, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin10, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin11, Mode_IPU);
        break;
    case UART_4:
        WHT_GPIO_BSP.WHT_Set_Clock(PortC, ENABLE);
        WHT_GPIO_BSP.WHT_Set_State(PortC, Pin10 | Pin11, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortC, Pin10, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortC, Pin11, Mode_IPU);
        break;
    case UART_5:
        WHT_GPIO_BSP.WHT_Set_Clock(PortC, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Clock(PortD, ENABLE);
        WHT_GPIO_BSP.WHT_Set_State(PortC, Pin12, Hig);
        WHT_GPIO_BSP.WHT_Set_State(PortD, Pin2, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortC, Pin12, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortD, Pin2, Mode_IPU);
        break;
    default:
        break;
    }
}
/*串口中断优先级配置*/
static void WHT_UART_BSP_NVIC_Configuration(const WHT_UART_Config_t *config)
{
    NVIC_InitTypeDef NVIC_InitStruct;

    /* 嵌套向量中断控制器组选择 */
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    /* 配置中断源 */
    switch (config->Name)
    {
    case UART_1:NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; break;
    case UART_2:NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; break;
    case UART_3:NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn; break;
#ifdef STM32F10X_HD
    case UART_4:NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn; break;
    case UART_5:NVIC_InitStruct.NVIC_IRQChannel = UART5_IRQn; break;
#endif /* STM32F10X_HD */  
    default:
        return;
    }
    /* 抢断优先级*/
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = config->PreemptionPriority;
    /* 子优先级 */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = config->SubPriority;
    /* 使能中断 */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* 初始化配置NVIC */
    NVIC_Init(&NVIC_InitStruct);
}
/*串口注册*/
static ErrorStatus WHT_UART_BSP_Register(const WHT_UART_Config_t* config, const WHT_UART_Cache_t* cache)
{
    if ((WHT_UART != NULL) && (cache->Info != NULL))
        return SUCCESS;
    
    switch (config->Name)
    {
    case UART_1:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART1; break;
    case UART_2:RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART2; break;
    case UART_3:RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART3; break;
    case UART_4:RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);  ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART4; break;
    case UART_5:RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);  ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART5; break;
    default: return ERROR;
    }

    WHT_UART->Name = config->Name;
    ((WHT_UART_Cache_t*)cache)->Info = &WHT_UART->Info;
    WHT_UART->DMA_Send_Config.IT_Callback = NULL;
    WHT_UART->DMA_Receive_Config.IT_Callback = NULL;

    /*串口中断优先级配置*/
    WHT_UART_BSP_NVIC_Configuration(config);

    //将串口注册到DMA上
    switch (config->Name)
    {
    case UART_1:WHT_UART->DMA_Send_Config.Name = Source_USART1_TX;WHT_UART->DMA_Receive_Config.Name = Source_USART1_RX;break;
    case UART_2:WHT_UART->DMA_Send_Config.Name = Source_USART2_TX;WHT_UART->DMA_Receive_Config.Name = Source_USART2_RX;break;
    case UART_3:WHT_UART->DMA_Send_Config.Name = Source_USART3_TX;WHT_UART->DMA_Receive_Config.Name = Source_USART3_RX;break;
    case UART_4:WHT_UART->DMA_Send_Config.Name = Source_UART4_TX; WHT_UART->DMA_Receive_Config.Name = Source_UART4_RX; break;
    case UART_5:return SUCCESS;//串口5没有DMA
    }
    WHT_DMA_BSP.WHT_Register(&WHT_UART->DMA_Send_Config);
    WHT_DMA_BSP.WHT_Register(&WHT_UART->DMA_Receive_Config);
    return SUCCESS;
}
/*串口配置*/
static void WHT_UART_BSP_Config(const WHT_UART_Config_t* config, const WHT_UART_Cache_t* cache)
{
    USART_InitTypeDef USART_InitStruct;
    
    if ((WHT_UART == NULL) || (cache->Info == NULL))
        return;

    WHT_UART->Cache = (WHT_UART_Cache_t*)cache;

    /*临时关闭串口*/
    USART_Cmd((USART_TypeDef*)WHT_UART->Name, DISABLE);
    /*串口相关GPIO初始化*/
    WHT_UART_BSP_GPIO_Init(config);

    /*初始化配置串口相关寄存器*/
    USART_InitStruct.USART_BaudRate = config->Bps;                              //串口波特率
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;                    //数据长度    
    USART_InitStruct.USART_StopBits = config->StopBits << 12;                   //停止位个数
    USART_InitStruct.USART_Parity = config->Parity;                             //校验位个数
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件控制流
    USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;                //发送和接收
    USART_Init((USART_TypeDef*)WHT_UART->Name, &USART_InitStruct);

    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_RXNE, DISABLE);//关闭中断串口接收
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_IDLE, DISABLE);//关闭中断串口空闲
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TXE, DISABLE); //关闭发送寄存器为空进入中断
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TC, DISABLE);  //关闭数据发送完成且发送寄存器为空进入中断

    /*使能串口*/
    USART_Cmd((USART_TypeDef*)WHT_UART->Name, ENABLE);
}


/*串口阻塞发送*/
static void WHT_UART_BSP_Send(const WHT_UART_Cache_t* cache)
{
    WHT_UART->Info.Tx_State = UART_Tx_Busy;
    USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Tx, DISABLE);//关闭串口发送DMA请求
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TXE, DISABLE);
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TC, DISABLE);
    USART_ClearFlag((USART_TypeDef*)WHT_UART->Name, USART_FLAG_TC);        //清除上次发送完成状态
    for (unsigned int tx_count = 0; tx_count < WHT_UART->Cache->Tx_Count; tx_count++)
    {
        USART_SendData((USART_TypeDef*)WHT_UART->Name, WHT_UART->Cache->Tx_Buf[tx_count]);
        while (!USART_GetFlagStatus((USART_TypeDef*)WHT_UART->Name, USART_FLAG_TXE));//等待发送寄存器为空
    }
    while (!USART_GetFlagStatus((USART_TypeDef*)WHT_UART->Name, USART_FLAG_TC));     //等待发送完成且发送寄存器为空
    WHT_UART->Info.Tx_State = UART_Tx_Idle;
}
/*串口中断发送*/
static void WHT_UART_BSP_Interrupt_Send(const WHT_UART_Cache_t* cache)
{
    WHT_UART->Info.Tx_State = UART_Tx_Busy;
    USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Tx, DISABLE);//关闭串口发送DMA请求
    /*默认寄存器TC=1,TXE=1*/
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TXE, ENABLE);  //使能发送寄存器为空进入中断
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TC, ENABLE);   //使能数据发送完成且发送寄存器为空进入中断
}
/*串口DMA发送*/
static void WHT_UART_BSP_DMA_Send(const WHT_UART_Cache_t* cache)
{
    DMA_InitTypeDef DMA_InitStruct =
    {
        //.DMA_PeripheralBaseAddr = 0,                        //外设基地址
        //.DMA_MemoryBaseAddr     = NULL,                     //默认值
        .DMA_DIR                = DMA_DIR_PeripheralDST,      //M->P
        //.DMA_BufferSize         = 0,                        //默认值
        .DMA_PeripheralInc      = DMA_PeripheralInc_Disable,  //外设地址不递增
        .DMA_MemoryInc          = DMA_MemoryInc_Enable,       //存储器地址递增
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,//外设数据大小为字节
        .DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte,    //存储器数据大小为字节，跟外设数据大小相同
        .DMA_Mode               = DMA_Mode_Normal,            //单次传输模式
        .DMA_Priority           = DMA_Priority_Low,           //优先级最低
        .DMA_M2M                = DMA_M2M_Disable,            //禁止存储器到存储器模式，因为是从存储器到外设
    };

    switch (WHT_UART->Name)
    {
    case UART_1:DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&USART1->DR;break;//外设基地址
    case UART_2:DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&USART2->DR;break;
    case UART_3:DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&USART3->DR;break;
    case UART_4:DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&UART4->DR; break;
    case UART_5:WHT_UART_BSP_Interrupt_Send(cache);return;//STM32F103没有串口5的DMA功能故这里走中断发送
    default:
        return;
    }
    DMA_InitStruct.DMA_MemoryBaseAddr = (unsigned int)WHT_UART->Cache->Tx_Buf;//数据源首地址
    DMA_InitStruct.DMA_BufferSize = WHT_UART->Cache->Tx_Count;            //传输数据个数
    WHT_UART->DMA_Send_Config.DMA_InitStruct = &DMA_InitStruct;

    WHT_UART->Info.Tx_State = UART_Tx_Busy;//发送置为忙碌;
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TXE, DISABLE);//发送寄存器为空
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TC, DISABLE); //数据发送完成且发送寄存器为空

    while (WHT_UART->DMA_Send_Config.Info->BSP_Mutex == SET);//等待没有外设使用此通道的DMA
    WHT_UART->DMA_Send_Config.Info->BSP_Mutex = SET;         //DMA通道上锁
    WHT_DMA_BSP.WHT_Config(&WHT_UART->DMA_Send_Config);      //配置当前DMA

    USART_ClearFlag((USART_TypeDef*)WHT_UART->Name, USART_FLAG_TC);
    USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Tx, ENABLE);//使能串口DMA发送请求
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TC, ENABLE);  //数据发送完成且发送寄存器为空
}

/*串口中断接收*/
static void WHT_UART_BSP_Interrupt_Receive(const WHT_UART_Cache_t* cache)
{
    USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Rx, DISABLE);//关闭串口DMA接收请求

    WHT_UART->Info.Rx_State = UART_Rx_Idle;
    WHT_UART->Cache->Rx_Count = 0;
    WHT_UART->Dma_Receive = DISABLE;

    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_RXNE, ENABLE);//接收寄存器非空
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_IDLE, ENABLE);//数据接收完成且总线空闲
    ((USART_TypeDef*)WHT_UART->Name)->CR1 |= USART_Mode_Rx;               //开启串口接收
}
/*串口DMA接收*/
static void WHT_UART_BSP_DMA_Receive(const WHT_UART_Cache_t* cache)
{
    DMA_InitTypeDef DMA_InitStruct =
    {
        //.DMA_PeripheralBaseAddr = (unsigned int)&USART1->DR,//外设基地址
        //.DMA_MemoryBaseAddr     = NULL,                     //默认值
        .DMA_DIR                = DMA_DIR_PeripheralSRC,      //P->M
        //.DMA_BufferSize         = 0,                        //默认值
        .DMA_PeripheralInc      = DMA_PeripheralInc_Disable,  //外设地址不递增
        .DMA_MemoryInc          = DMA_MemoryInc_Enable,       //存储器地址递增
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,//外设数据大小为字节
        .DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte,    //存储器数据大小为字节，跟外设数据大小相同
        .DMA_Mode               = DMA_Mode_Normal,            //单次传输模式
        .DMA_Priority           = DMA_Priority_Low,           //优先级最低
        .DMA_M2M                = DMA_M2M_Disable,            //禁止存储器到存储器模式，因为是从存储器到外设
    };

    WHT_UART->DMA_Receive_Config.DMA_InitStruct = &DMA_InitStruct;
    switch (WHT_UART->Name)
    {
    case UART_1:WHT_UART->DMA_Receive_Config.DMA_InitStruct->DMA_PeripheralBaseAddr = (unsigned int)&USART1->DR;break;//外设基地址
    case UART_2:WHT_UART->DMA_Receive_Config.DMA_InitStruct->DMA_PeripheralBaseAddr = (unsigned int)&USART2->DR;break;
    case UART_3:WHT_UART->DMA_Receive_Config.DMA_InitStruct->DMA_PeripheralBaseAddr = (unsigned int)&USART3->DR;break;
    case UART_4:WHT_UART->DMA_Receive_Config.DMA_InitStruct->DMA_PeripheralBaseAddr = (unsigned int)&UART4->DR; break;
    case UART_5:WHT_UART_BSP_Interrupt_Receive(cache);return;//STM32F103没有串口5的DMA功能故这里走中断接收
    default:
        return;
    }
    WHT_UART->DMA_Receive_Config.DMA_InitStruct->DMA_MemoryBaseAddr = (unsigned int)WHT_UART->Cache->Rx_Buf;//数据源首地址
    WHT_UART->DMA_Receive_Config.DMA_InitStruct->DMA_BufferSize = WHT_UART->Cache->Rx_Buf_Size;             //传输数据个数

    WHT_UART->Info.Rx_State = UART_Rx_Idle;
    WHT_UART->Dma_Receive = ENABLE;
    WHT_UART->Cache->Rx_Count = 0;

    while (WHT_UART->DMA_Receive_Config.Info->BSP_Mutex == SET);//没有外设使用此通道的DMA
    WHT_UART->DMA_Receive_Config.Info->BSP_Mutex = SET;         //开启互斥锁
    WHT_DMA_BSP.WHT_Config(&WHT_UART->DMA_Receive_Config);      //配置当前DMA

    USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Rx, ENABLE); //使能串口DMA接收请求
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_RXNE, DISABLE);//接收寄存器非空
    USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_IDLE, ENABLE); //数据接收完成且总线空闲
    ((USART_TypeDef*)WHT_UART->Name)->CR1 |= USART_Mode_Rx;                //开启串口接收
}

/*全局常量*/
const WHT_UART_BSP_t WHT_UART_BSP =
{
    .WHT_Register          = WHT_UART_BSP_Register,
    .WHT_Config            = WHT_UART_BSP_Config,
    .WHT_Send              = WHT_UART_BSP_Send,
    .WHT_Interrupt_Send    = WHT_UART_BSP_Interrupt_Send,
    .WHT_DMA_Send          = WHT_UART_BSP_DMA_Send,
    .WHT_DMA_Receive       = WHT_UART_BSP_DMA_Receive,
    .WHT_Interrupt_Receive = WHT_UART_BSP_Interrupt_Receive,
};





/*串口中断发送回调函数*/
static void WHT_UART_BSP_IRQHandler_Send(const WHT_UART_Cache_t* cache, unsigned int* tx_count)
{
    if (USART_GetITStatus((USART_TypeDef*)WHT_UART->Name, USART_IT_TXE) == SET)//发送寄存器为空
    {
        if (*tx_count >= WHT_UART->Cache->Tx_Count)//是否数据发送完
        {
            USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TXE, DISABLE);
            *tx_count = 0;
        }
        else
        {
            USART_SendData((USART_TypeDef*)WHT_UART->Name, WHT_UART->Cache->Tx_Buf[(*tx_count)++]);
        }
    }
    else if (USART_GetITStatus((USART_TypeDef*)WHT_UART->Name, USART_IT_TC) == SET)//发送完成且发送寄存器为空
    {
        USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_TC, DISABLE);  //DMA发送有使用此串口中断，小心DMA未及时处理导致此中断发生
        USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Tx, DISABLE);//关闭DMA请求
        WHT_UART->Info.Tx_State = UART_Tx_Idle;
        if (WHT_UART->Cache->Tx_Idle_IT_Callback != NULL)
            WHT_UART->Cache->Tx_Idle_IT_Callback();
    }
}
/*串口中断接收回调函数*/
static void WHT_UART_BSP_IRQHandler_Receive(const WHT_UART_Cache_t* cache)
{
    if (WHT_UART->Dma_Receive == DISABLE)
    {
        if (USART_GetITStatus((USART_TypeDef*)WHT_UART->Name, USART_IT_RXNE) == SET)//接收寄存器非空
        {
            if (WHT_UART->Cache->Rx_Count >= WHT_UART->Cache->Rx_Buf_Size)//接收数据个数是否超标
                USART_ReceiveData((USART_TypeDef*)WHT_UART->Name);        //丢弃接收到的数据
            else
            {
                WHT_UART->Cache->Rx_Buf[WHT_UART->Cache->Rx_Count] = USART_ReceiveData((USART_TypeDef*)WHT_UART->Name);
                WHT_UART->Cache->Rx_Count++;
                WHT_UART->Info.Rx_State = UART_Rx_Busy;
            }
        }
        else if (USART_GetITStatus((USART_TypeDef*)WHT_UART->Name, USART_IT_IDLE) == SET)//接收空闲
        {
            ((USART_TypeDef*)WHT_UART->Name)->CR1 &= ~USART_Mode_Rx; //关闭串口接收
            USART_ReceiveData((USART_TypeDef*)WHT_UART->Name);       //读取一下接收寄存器数据清除空闲标志位
            WHT_UART->Info.Rx_State = WHT_UART->Cache->Rx_Count >= WHT_UART->Cache->Rx_Buf_Size ? UART_Rx_Overflow : UART_Rx_Idle;//接收数据个数是否超标
            if (WHT_UART->Cache->Rx_Idle_IT_Callback != NULL)
                WHT_UART->Cache->Rx_Idle_IT_Callback();
        }
    }
    else
    {
        if (USART_GetITStatus((USART_TypeDef*)WHT_UART->Name, USART_IT_IDLE) == SET)//接收空闲
        {
            ((USART_TypeDef*)WHT_UART->Name)->CR1 &= ~USART_Mode_Rx;               //关闭串口接收
            USART_ITConfig((USART_TypeDef*)WHT_UART->Name, USART_IT_IDLE, DISABLE);//数据接收完成且总线空闲
            USART_ReceiveData((USART_TypeDef*)WHT_UART->Name);                     //在读取一次接收到的数据,用来清除空闲标志位
            
            USART_DMACmd((USART_TypeDef*)WHT_UART->Name, USART_DMAReq_Rx, DISABLE);//关闭串口DMA接收请求
            WHT_UART->Cache->Rx_Count = WHT_UART->Cache->Rx_Buf_Size - WHT_DMA_BSP.WHT_Get_Curr_Data_Count(&WHT_UART->DMA_Receive_Config);
            WHT_DMA_BSP.WHT_Close(&WHT_UART->DMA_Receive_Config);      //手动关闭DMA通道
            WHT_UART->Info.Rx_State = UART_Rx_Idle;
            if (WHT_UART->Cache->Rx_Idle_IT_Callback != NULL)
                WHT_UART->Cache->Rx_Idle_IT_Callback();
        }
    }
}

/*串口1中断服务程序*/
void USART1_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART1.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART1.Cache);
}
/*串口2中断服务程序*/
void USART2_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART2.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART2.Cache);
}
/*串口3中断服务程序*/
void USART3_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART3.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART3.Cache);
}
/*串口4中断服务程序*/
void UART4_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART4.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART4.Cache);
}
/*串口5中断服务程序*/
void UART5_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART5.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART5.Cache);
}
